package org.nicocube.airain.game.client;

import java.util.List;

import org.nicocube.airain.common.client.AirainMessenger;
import org.nicocube.airain.domain.client.character.AttributeIdentifier;
import org.nicocube.airain.domain.client.character.GameCharacter;
import org.nicocube.airain.domain.client.character.ObservableGameCharacter;
import org.nicocube.airain.domain.client.character.SkillIdentifier;
import org.nicocube.airain.game.client.rpc.GCService;
import org.nicocube.airain.game.client.rpc.GCServiceAsync;
import org.nicocube.airain.game.client.ui.ActionSchedulerPanel;
import org.nicocube.airain.game.client.ui.ActivitiesLogPanel;
import org.nicocube.airain.game.client.ui.AttrAndSkillPanel;
import org.nicocube.airain.game.client.ui.ObserverLabel;
import org.nicocube.airain.game.client.ui.PossessionsPanel;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class AirainGame implements EntryPoint {

	public interface I18nConstants extends Constants{
		@DefaultStringValue("Please wait while loading.")
		String waitLoading();
	}

	private I18nConstants constants;
	private AirainMessenger messenger;

	private List<AttributeIdentifier> attributes;
	private List<SkillIdentifier> skills;

	private GCServiceAsync gcService;
	protected ObservableGameCharacter gc;
	
	@Override
	public void onModuleLoad() {
		constants = GWT.create(I18nConstants.class);
		
		messenger = new AirainMessenger();
		messenger.show(constants.waitLoading());

		gcService = GWT.create(GCService.class);

		gcService.retrieveGameCharacter(new AsyncCallback<GameCharacter>() {
			public void onFailure(Throwable caught) {

			}

			public void onSuccess(GameCharacter result) {
				gc = new ObservableGameCharacter(result);
				launchUI();
				messenger.hide();
			}
		});
	}

	private void launchUI() {

		DecoratorPanel rootPanel = new DecoratorPanel();
		rootPanel.addStyleName("rootPanel");

		VerticalPanel vp = new VerticalPanel();

		DecoratorPanel decPanel = new DecoratorPanel();
		decPanel.addStyleName("airain-name-panel");

		HorizontalPanel hp = new HorizontalPanel();
		hp.setSpacing(10);

		Label l1 = new Label(gc.getName());
		l1.setWidth("300px");
		l1.setWordWrap(false);

		hp.add(l1);

		Label l2 = new ObserverLabel<ObservableGameCharacter>((ObservableGameCharacter)gc) {
			@Override
			public String render(ObservableGameCharacter publisher) {
				String res = gc.getBirthdate().getAge(publisher.getLivedate());
				return res;
			}
		};
		// l2.setWidth("400px");
		l2.setWordWrap(false);

		hp.add(l2);

		decPanel.add(hp);

		vp.add(decPanel);

		DecoratedTabPanel tp = new DecoratedTabPanel();

		tp.setWidth("400px");
		tp.getDeckPanel().setAnimationEnabled(true);

		AttrAndSkillPanel f1 = new AttrAndSkillPanel(this);
		PossessionsPanel f2 = new PossessionsPanel(this);
		ActionSchedulerPanel f3 = new ActionSchedulerPanel(this);
		ActivitiesLogPanel f4 = new ActivitiesLogPanel(this);

		f1.addTo(tp);
		f2.addTo(tp);
		f3.addTo(tp);
		f4.addTo(tp);

		tp.selectTab(0);

		vp.add(tp);

		rootPanel.add(vp);

		// Add it to the root panel.
		RootPanel.get().add(rootPanel);
		
		Timer t = new Timer() {
			public void run() {
				gcService.updateGameCharacter(gc.getLivedate(),new AsyncCallback<GameCharacter>() {
					//@Override
					public void onFailure(Throwable caught) {
						messenger.show("Error while updating.");					
					}
					//@Override
					public void onSuccess(GameCharacter result) {
						if (result != null) {
							gc.synchronise(result);
						}
					}
					
				});
			}
		};

		// Schedule the timer to run once in 5 seconds.
		t.scheduleRepeating(10000);

	}

	public GameCharacter getGc() {
		return gc;
	}

	public AirainMessenger getMessenger() {
		return messenger;
	}

	public List<AttributeIdentifier> getAttributes() {
		return attributes;
	}

	public List<SkillIdentifier> getSkills() {
		return skills;
	}
}
